import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import json
import shutil
import os
import threading

class ToolTip:
    def __init__(self, widget, text='widget info'):
        self.widget = widget
        self.text = text
        self.widget.bind("<Enter>", self.showtip)
        self.widget.bind("<Leave>", self.hidetip)

    def showtip(self, event=None):
        x, y, cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx() + 25
        y = y + cy + self.widget.winfo_rooty() + 25
        self.tipwindow = tw = tk.Toplevel(self.widget)
        tw.wm_overrideredirect(True)
        tw.wm_geometry(f"+{x}+{y}")
        label = tk.Label(tw, text=self.text, justify='left',
                         background="#ffffe0", relief='solid', borderwidth=1,
                         font=("tahoma", "8", "normal"))
        label.pack(ipadx=1)

    def hidetip(self, event=None):
        tw = self.tipwindow
        self.tipwindow = None
        if tw:
            tw.destroy()

def select_json_file():
    file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
    if not file_path:
        messagebox.showwarning("警告", "未选择文件")
        log_message("警告: 未选择文件")
        return

    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            config = json.load(file)
            json_text.delete(1.0, tk.END)
            json_text.insert(tk.END, json.dumps(config, ensure_ascii=False, indent=4))
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON文件时出错: {e}")
        log_message(f"错误: 解析JSON文件时出错: {e}")
        return

    # 禁用文本框加载按钮
    load_json_button.config(state=tk.DISABLED)
    log_message(f"成功: 加载JSON文件: {file_path}")


def load_json_from_text():
    json_content = json_text.get(1.0, tk.END).strip()
    if not json_content:
        messagebox.showwarning("警告", "JSON内容为空")
        log_message("警告: JSON内容为空")
        return

    # 增加JSON格式以符合预期，并正确添加换行符和缩进
    json_content = f'{{\n    "game": {{\n        "mods": [\n            {json_content}\n        ]\n    }}\n}}'

    try:
        config = json.loads(json_content)
        json_text.delete(1.0, tk.END)
        json_text.insert(tk.END, json.dumps(config, ensure_ascii=False, indent=4))
        json_path_entry.delete(0, tk.END)
        json_path_entry.insert(0, "从文本框导入的JSON")
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON内容时出错: {e}")
        log_message(f"错误: 解析JSON内容时出错: {e}")
        return

    # 禁用文件选择加载按钮
    json_button.config(state=tk.DISABLED)
    log_message("成功: 从文本框加载JSON内容")


def select_source_folder():
    folder_path = filedialog.askdirectory()
    source_folder_entry.delete(0, tk.END)
    source_folder_entry.insert(0, folder_path)

def select_target_folder():
    folder_path = filedialog.askdirectory()
    target_folder_entry.delete(0, tk.END)
    target_folder_entry.insert(0, folder_path)

def log_message(message):
    def update_log():
        log_text.insert(tk.END, message + "\n")
        log_text.see(tk.END)
        root.update_idletasks()
    root.after(0, update_log)

def copy_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    json_content = json_text.get(1.0, tk.END).strip()
    source_folder = source_folder_entry.get()
    target_folder = target_folder_entry.get()

    if not json_content:
        messagebox.showerror("错误", "JSON内容为空")
        log_message("错误: JSON内容为空")
        return

    try:
        config = json.loads(json_content)
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON内容时出错: {e}")
        log_message(f"错误: 解析JSON内容时出错: {e}")
        return

    if 'game' not in config or 'mods' not in config['game']:
        messagebox.showerror("错误", "JSON文件格式不正确")
        log_message("错误: JSON文件格式不正确")
        return

    mods = config['game']['mods']
    total_mods = len(mods)
    found_and_copied = False
    mod_info = {}

    # 初始化进度条
    progress['value'] = 0
    progress.update_idletasks()

    try:
        for index, mod in enumerate(mods):
            mod_id = mod.get('modId', '')
            if not mod_id:
                log_message("错误: 模组ID为空")
                continue
            log_message(f"正在查找模组ID: {mod_id}")
            for folder_name in os.listdir(source_folder):
                if mod_id in folder_name:
                    # 提取模组名称和模组ID
                    if f"_{mod_id}" in folder_name:
                        mod_name = folder_name.split(f"_{mod_id}")[0]
                    else:
                        mod_name = folder_name
                        mod_id = ''  # 或者从其他地方获取模组ID

                    mod_source_path = os.path.join(source_folder, folder_name)
                    mod_target_path = os.path.join(target_folder, folder_name)
                    log_message(f"找到模组文件夹: {folder_name}")

                    if os.path.isdir(mod_source_path):
                        try:
                            # 检查目标文件夹中是否存在该模组文件夹
                            target_mod_version = None
                            target_server_data_path = os.path.join(mod_target_path, 'ServerData.json')
                            if os.path.exists(mod_target_path) and os.path.isdir(mod_target_path):
                                if os.path.isfile(target_server_data_path):
                                    with open(target_server_data_path, 'r', encoding='utf-8-sig') as target_server_file:
                                        target_server_data = json.load(target_server_file)
                                        target_mod_version = target_server_data.get('revision', {}).get('version', '')
                            else:
                                log_message(f"警告: 目标文件夹中的 {folder_name} 没有 ServerData.json 文件")

                            # 读取源文件夹中的 ServerData.json 文件
                            source_server_data_path = os.path.join(mod_source_path, 'ServerData.json')
                            if os.path.isfile(source_server_data_path):
                                with open(source_server_data_path, 'r', encoding='utf-8-sig') as source_server_file:
                                    source_server_data = json.load(source_server_file)
                                    source_mod_name = source_server_data.get('id', '')
                                    source_mod_version = source_server_data.get('revision', {}).get('version', '')
                                    log_message(f"源模组版本: {source_mod_version}")
                            else:
                                messagebox.showwarning("警告", f"源文件夹中的 {folder_name} 没有 ServerData.json 文件")
                                log_message(f"警告: 源文件夹中的 {folder_name} 没有 ServerData.json 文件")
                                continue

                            # 比较版本信息
                            if target_mod_version is None or source_mod_version != target_mod_version:
                                log_message(f"版本不匹配或目标文件夹中没有该模组: {source_mod_version} != {target_mod_version}")
                                # 复制模组文件夹到目标文件夹
                                shutil.copytree(mod_source_path, mod_target_path, dirs_exist_ok=True)
                                log_message(f"复制模组文件夹: {folder_name} 到 {mod_target_path}")

                                # 压缩模组文件夹
                                zip_path = os.path.join(target_folder, f"{folder_name}.zip")
                                shutil.make_archive(os.path.splitext(zip_path)[0], 'zip', root_dir=target_folder, base_dir=folder_name)
                                log_message(f"压缩模组文件夹: {folder_name} 到 {zip_path}")

                                # 删除原始文件夹
                                shutil.rmtree(mod_target_path)
                                log_message(f"删除原始模组文件夹: {mod_target_path}")

                                # 记录模组信息，包括名称和ID
                                mod_info[mod_id] = {'name': mod_name, 'version': source_mod_version}
                                log_message(f"记录模组信息: {mod_name} ({mod_id}) - {source_mod_version}")
                                found_and_copied = True
                            else:
                                log_message(f"版本匹配: {source_mod_version} == {target_mod_version}")
                                mod_info[mod_id] = {'name': mod_name, 'version': source_mod_version}
                                log_message(f"记录模组信息: {mod_name} ({mod_id}) - {source_mod_version}")
                        except Exception as e:
                            messagebox.showerror("错误", f"复制模组 {folder_name} 时出错: {e}")
                            log_message(f"错误: 复制模组 {folder_name} 时出错: {e}")
                    else:
                        messagebox.showwarning("警告", f"模组文件夹 {folder_name} 不是文件夹")
                        log_message(f"警告: 模组文件夹 {folder_name} 不是文件夹")
                else:
                    log_message(f"模组文件夹 {folder_name} 不包含模组ID: {mod_id}")

            # 更新进度条
            progress['value'] = (index + 1) / total_mods * 100
            progress.update_idletasks()

        if not found_and_copied:
            messagebox.showwarning("警告", "没有找到任何需要更新的模组文件夹")
            log_message("警告: 没有找到任何需要更新的模组文件夹")
        else:
            mod_info_file_path = os.path.join(target_folder, 'mod_info.json')
            with open(mod_info_file_path, 'w', encoding='utf-8') as mod_info_file:
                json.dump(mod_info, mod_info_file, ensure_ascii=False, indent=4)
            messagebox.showinfo("成功", "所有需要更新的模组文件夹已复制到目标文件夹，压缩并生成了模组信息文件")
            log_message(f"成功: 生成模组信息文件: {mod_info_file_path}")
    except Exception as e:
        messagebox.showerror("错误", f"操作过程中出错: {e}")
        log_message(f"错误: 操作过程中出错: {e}")

def only_copy_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    json_content = json_text.get(1.0, tk.END).strip()
    source_folder = source_folder_entry.get()
    target_folder = target_folder_entry.get()

    if not json_content:
        messagebox.showerror("错误", "JSON内容为空")
        log_message("错误: JSON内容为空")
        return


    try:
        config = json.loads(json_content)
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON内容时出错: {e}")
        log_message(f"错误: 解析JSON内容时出错: {e}")
        return

    if 'game' not in config or 'mods' not in config['game']:
        messagebox.showerror("错误", "JSON文件格式不正确")
        log_message("错误: JSON文件格式不正确")
        return

    mods = config['game']['mods']
    total_mods = len(mods)
    found_and_copied = False

    # 初始化进度条
    progress['value'] = 0
    progress.update_idletasks()

    try:
        for index, mod in enumerate(mods):
            mod_id = mod.get('modId', '')
            if not mod_id:
                log_message("错误: 模组ID为空")
                continue
            log_message(f"正在查找模组ID: {mod_id}")
            for folder_name in os.listdir(source_folder):
                if mod_id in folder_name:
                    mod_source_path = os.path.join(source_folder, folder_name)
                    mod_target_path = os.path.join(target_folder, folder_name)
                    log_message(f"找到模组文件夹: {folder_name}")

                    if os.path.isdir(mod_source_path):
                        try:
                            # 复制模组文件夹到目标文件夹
                            shutil.copytree(mod_source_path, mod_target_path, dirs_exist_ok=True)
                            log_message(f"复制模组文件夹: {folder_name} 到 {mod_target_path}")
                            found_and_copied = True
                        except Exception as e:
                            messagebox.showerror("错误", f"复制模组 {folder_name} 时出错: {e}")
                            log_message(f"错误: 复制模组 {folder_name} 时出错: {e}")
                    else:
                        messagebox.showwarning("警告", f"模组文件夹 {folder_name} 不是文件夹")
                        log_message(f"警告: 模组文件夹 {folder_name} 不是文件夹")
                else:
                    log_message(f"模组文件夹 {folder_name} 不包含模组ID: {mod_id}")

            # 更新进度条
            progress['value'] = (index + 1) / total_mods * 100
            progress.update_idletasks()

        if not found_and_copied:
            messagebox.showwarning("警告", "没有找到任何需要更新的模组文件夹")
            log_message("警告: 没有找到任何需要更新的模组文件夹")
        else:
            messagebox.showinfo("成功", "所有需要更新的模组文件夹已复制到目标文件夹")
            log_message("成功: 所有需要更新的模组文件夹已复制到目标文件夹")
    except Exception as e:
        messagebox.showerror("错误", f"操作过程中出错: {e}")
        log_message(f"错误: 操作过程中出错: {e}")

def only_export_json():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    json_content = json_text.get(1.0, tk.END).strip()
    source_folder = source_folder_entry.get()
    target_folder = target_folder_entry.get()

    if not json_content:
        messagebox.showerror("错误", "JSON内容为空")
        log_message("错误: JSON内容为空")
        return

    try:
        config = json.loads(json_content)
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON内容时出错: {e}")
        log_message(f"错误: 解析JSON内容时出错: {e}")
        return

    if 'game' not in config or 'mods' not in config['game']:
        messagebox.showerror("错误", "JSON文件格式不正确")
        log_message("错误: JSON文件格式不正确")
        return

    mods = config['game']['mods']
    total_mods = len(mods)
    mod_info = {}

    try:
        for index, mod in enumerate(mods):
            mod_id = mod.get('modId', '')
            if not mod_id:
                log_message("错误: 模组ID为空")
                continue
            log_message(f"正在查找模组ID: {mod_id}")
            for folder_name in os.listdir(source_folder):
                if mod_id in folder_name:
                    # 提取模组名称
                    mod_name = folder_name.split(f"_{mod_id}")[0] if f"_{mod_id}" in folder_name else folder_name
                    mod_source_path = os.path.join(source_folder, folder_name)

                    if os.path.isdir(mod_source_path):
                        try:
                            # 读取源文件夹中的 ServerData.json 文件
                            source_server_data_path = os.path.join(mod_source_path, 'ServerData.json')
                            if os.path.isfile(source_server_data_path):
                                with open(source_server_data_path, 'r', encoding='utf-8-sig') as source_server_file:
                                    source_server_data = json.load(source_server_file)
                                    source_mod_name = source_server_data.get('id', '')
                                    source_mod_version = source_server_data.get('revision', {}).get('version', '')
                                    log_message(f"源模组版本: {source_mod_version}")
                            else:
                                messagebox.showwarning("警告", f"源文件夹中的 {folder_name} 没有 ServerData.json 文件")
                                log_message(f"警告: 源文件夹中的 {folder_name} 没有 ServerData.json 文件")
                                continue

                            # 记录模组信息，包括名称和ID
                            mod_info[mod_id] = {'name': mod_name, 'version': source_mod_version}
                            log_message(f"记录模组信息: {mod_name} ({mod_id}) - {source_mod_version}")
                        except Exception as e:
                            messagebox.showerror("错误", f"处理模组 {folder_name} 时出错: {e}")
                            log_message(f"错误: 处理模组 {folder_name} 时出错: {e}")
                    else:
                        messagebox.showwarning("警告", f"模组文件夹 {folder_name} 不是文件夹")
                        log_message(f"警告: 模组文件夹 {folder_name} 不是文件夹")
                else:
                    log_message(f"模组文件夹 {folder_name} 不包含模组ID: {mod_id}")

            # 更新进度条
            progress['value'] = (index + 1) / total_mods * 100
            progress.update_idletasks()

        if not mod_info:
            messagebox.showwarning("警告", "没有找到任何模组文件夹")
            log_message("警告: 没有找到任何模组文件夹")
        else:
            mod_info_file_path = os.path.join(target_folder, 'mod_info.json')
            with open(mod_info_file_path, 'w', encoding='utf-8') as mod_info_file:
                json.dump(mod_info, mod_info_file, ensure_ascii=False, indent=4)
            messagebox.showinfo("成功", f"模组信息文件已生成: {mod_info_file_path}")
            log_message(f"成功: 生成模组信息文件: {mod_info_file_path}")
    except Exception as e:
        messagebox.showerror("错误", f"操作过程中出错: {e}")
        log_message(f"错误: 操作过程中出错: {e}")

def zip_all_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    json_content = json_text.get(1.0, tk.END).strip()
    source_folder = source_folder_entry.get()
    target_folder = target_folder_entry.get()

    if not json_content:
        messagebox.showerror("错误", "JSON内容为空")
        log_message("错误: JSON内容为空")
        return



    try:
        config = json.loads(json_content)
    except Exception as e:
        messagebox.showerror("错误", f"解析JSON内容时出错: {e}")
        log_message(f"错误: 解析JSON内容时出错: {e}")
        return

    if 'game' not in config or 'mods' not in config['game']:
        messagebox.showerror("错误", "JSON文件格式不正确")
        log_message("错误: JSON文件格式不正确")
        return

    mods = config['game']['mods']
    total_mods = len(mods)
    found_and_copied = False

    # 初始化进度条
    progress['value'] = 0
    progress.update_idletasks()

    try:
        for index, mod in enumerate(mods):
            mod_id = mod.get('modId', '')
            if not mod_id:
                log_message("错误: 模组ID为空")
                continue
            log_message(f"正在查找模组ID: {mod_id}")
            for folder_name in os.listdir(source_folder):
                if mod_id in folder_name:
                    mod_source_path = os.path.join(source_folder, folder_name)
                    log_message(f"找到模组文件夹: {folder_name}")

                    if os.path.isdir(mod_source_path):
                        try:
                            # 复制模组文件夹到目标文件夹
                            mod_target_path = os.path.join(target_folder, folder_name)
                            shutil.copytree(mod_source_path, mod_target_path, dirs_exist_ok=True)
                            log_message(f"复制模组文件夹: {folder_name} 到 {mod_target_path}")
                            found_and_copied = True
                        except Exception as e:
                            messagebox.showerror("错误", f"复制模组 {folder_name} 时出错: {e}")
                            log_message(f"错误: 复制模组 {folder_name} 时出错: {e}")
                    else:
                        messagebox.showwarning("警告", f"模组文件夹 {folder_name} 不是文件夹")
                        log_message(f"警告: 模组文件夹 {folder_name} 不是文件夹")
                else:
                    log_message(f"模组文件夹 {folder_name} 不包含模组ID: {mod_id}")

            # 更新进度条
            progress['value'] = (index + 1) / total_mods * 100
            progress.update_idletasks()

        if not found_and_copied:
            messagebox.showwarning("警告", "没有找到任何需要更新的模组文件夹")
            log_message("警告: 没有找到任何需要更新的模组文件夹")
        else:
            # 创建一个临时文件夹来存储所有模组文件夹
            all_mods_folder = os.path.join(target_folder, 'all_mods')
            os.makedirs(all_mods_folder, exist_ok=True)
            for folder_name in os.listdir(target_folder):
                folder_path = os.path.join(target_folder, folder_name)
                if os.path.isdir(folder_path) and folder_name != 'all_mods':
                    shutil.move(folder_path, all_mods_folder)
                    log_message(f"移动模组文件夹: {folder_name} 到 {all_mods_folder}")

            # 压缩临时文件夹中的所有模组文件夹
            zip_path = os.path.join(target_folder, 'all_mods.zip')
            shutil.make_archive(os.path.splitext(zip_path)[0], 'zip', root_dir=all_mods_folder)
            log_message(f"压缩所有模组文件夹: {all_mods_folder} 到 {zip_path}")

            # 删除临时文件夹
            shutil.rmtree(all_mods_folder)
            log_message(f"删除临时文件夹: {all_mods_folder}")

            messagebox.showinfo("成功", f"所有模组文件夹已复制并打包成一个压缩包: {zip_path}")
            log_message(f"成功: 所有模组文件夹已复制并打包成一个压缩包: {zip_path}")
    except Exception as e:
        messagebox.showerror("错误", f"操作过程中出错: {e}")
        log_message(f"错误: 操作过程中出错: {e}")

def run_copy_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    copy_button.config(state=tk.DISABLED)  # 禁用复制按钮
    thread = threading.Thread(target=copy_mods)
    thread.start()

def run_only_copy_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    only_copy_button.config(state=tk.DISABLED)  # 禁用仅复制按钮
    thread = threading.Thread(target=only_copy_mods)
    thread.start()

def run_only_export_json():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    only_export_json_button.config(state=tk.DISABLED)  # 禁用仅导出JSON按钮
    thread = threading.Thread(target=only_export_json)
    thread.start()

def run_zip_all_mods():
    log_text.delete(1.0, tk.END)  # 清空日志文本框
    zip_all_mods_button.config(state=tk.DISABLED)  # 禁用打包按钮
    thread = threading.Thread(target=zip_all_mods)
    thread.start()

# 创建主窗口
root = tk.Tk()
root.title("模组用户工具——作者ViVi141_QQ:747384120")
root.geometry("750x750")  # 调整窗口大小以容纳新控件

# 创建JSON文件路径标签和输入框
json_label = tk.Label(root, text="选择服务器用JSON文件:")
json_label.grid(row=0, column=0, padx=10, pady=10, sticky=tk.W)

json_path_entry = tk.Entry(root, width=50)
json_path_entry.grid(row=0, column=1, padx=10, pady=10)

json_button = tk.Button(root, text="浏览", command=select_json_file)
json_button.grid(row=0, column=2, padx=10, pady=10)

# 创建JSON文本框
json_text_label = tk.Label(root, text="粘贴游戏中JSON内容:")
json_text_label.grid(row=1, column=0, padx=10, pady=10, sticky=tk.W)

json_text = tk.Text(root, width=65, height=10, wrap=tk.WORD)
json_text.grid(row=1, column=1, columnspan=2, padx=10, pady=10)

# 创建加载JSON按钮
load_json_button = tk.Button(root, text="加载JSON", command=load_json_from_text)
load_json_button.grid(row=1, column=3, padx=10, pady=10)

# 创建源文件夹路径标签和输入框
source_label = tk.Label(root, text="选择源文件夹:")
source_label.grid(row=2, column=0, padx=10, pady=10, sticky=tk.W)

source_folder_entry = tk.Entry(root, width=50)
source_folder_entry.grid(row=2, column=1, padx=10, pady=10)

source_button = tk.Button(root, text="浏览", command=select_source_folder)
source_button.grid(row=2, column=2, padx=10, pady=10)

# 创建目标文件夹路径标签和输入框
target_label = tk.Label(root, text="选择目标文件夹:")
target_label.grid(row=3, column=0, padx=10, pady=10, sticky=tk.W)

target_folder_entry = tk.Entry(root, width=50)
target_folder_entry.grid(row=3, column=1, padx=10, pady=10)

target_button = tk.Button(root, text="浏览", command=select_target_folder)
target_button.grid(row=3, column=2, padx=10, pady=10)

# 创建进度条
progress_label = tk.Label(root, text="进度:")
progress_label.grid(row=4, column=0, padx=10, pady=10, sticky=tk.W)

progress = ttk.Progressbar(root, orient="horizontal", length=300, mode="determinate")
progress.grid(row=4, column=1, columnspan=2, padx=10, pady=10)

# 创建复制按钮（复制模组并导出JSON）
copy_button = tk.Button(root, text="复制模组并单独压缩每个模组并导出模组信息文件", command=run_copy_mods)
copy_button.grid(row=5, column=0, columnspan=3, pady=20)
ToolTip(copy_button, "复制所有需要更新的模组文件夹到目标文件夹，并压缩每个模组文件夹，生成模组信息文件。")

# 创建仅复制按钮
only_copy_button = tk.Button(root, text="仅复制模组", command=run_only_copy_mods)
only_copy_button.grid(row=6, column=0, columnspan=3, pady=10)
ToolTip(only_copy_button, "仅复制所有需要更新的模组文件夹到目标文件夹，不进行压缩和删除操作。")

# 创建仅导出JSON按钮
only_export_json_button = tk.Button(root, text="仅导出模组信息文件", command=run_only_export_json)
only_export_json_button.grid(row=7, column=0, columnspan=3, pady=10)
ToolTip(only_export_json_button, "仅生成模组信息文件，不进行复制和压缩操作。")

# 创建打包按钮（复制模组并打包成一个压缩包）
zip_all_mods_button = tk.Button(root, text="复制模组和生成模组信息文件并打包成一个压缩包", command=run_zip_all_mods)
zip_all_mods_button.grid(row=8, column=0, columnspan=3, pady=10)
ToolTip(zip_all_mods_button, "复制所有需要更新的模组文件夹到目标文件夹与生成模组信息文件，并将这些文件夹打包成一个单独的压缩包，不进行嵌套。")

# 创建日志文本框
log_label = tk.Label(root, text="日志信息:")
log_label.grid(row=9, column=0, padx=10, pady=10, sticky=tk.W)

log_text = tk.Text(root, width=65, height=10, wrap=tk.WORD)
log_text.grid(row=9, column=1, columnspan=2, padx=10, pady=10)

# 创建滚动条
scrollbar = tk.Scrollbar(root, command=log_text.yview)
scrollbar.grid(row=9, column=3, sticky=tk.NS)
log_text.config(yscrollcommand=scrollbar.set)

# 运行主循环
root.mainloop()
